package com.chuangjiangx.member.basic.web.config;

import com.chuangjiangx.member.basic.web.interceptor.CrossInterceptor;
import com.chuangjiangx.member.basic.web.interceptor.LoginInterceptor;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import java.io.File;
import java.util.List;

/**
 * @author zhangquanquan on 2018/7/2.
 */
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    public ObjectMapper objectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        //忽略json字符串中在Java对象中不存在的字段
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        return objectMapper;
    }

    @Bean
    public XmlMapper xmlMapper(){
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        return xmlMapper;
    }


    /**
     * 上传文件的解析器
     */
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //文件最大KB,MB
        factory.setMaxFileSize("100MB");
        //设置总上传数据总大小
        factory.setMaxRequestSize("200MB");
        //设置上传临时目录
        String location = System.getProperty("user.dir") + "/tmp/upload";
        File tmpFile = new File(location);
        if (!tmpFile.exists()) {
            tmpFile.mkdirs();
        }
        factory.setLocation(location);
        return factory.createMultipartConfig();
    }

    /**
     * 配置过滤器encodingFilterRegistration
     * @return
     */
    @Bean
    public FilterRegistrationBean encodingFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(encodingFilter());
        registration.addUrlPatterns("/*");
        registration.setName("encodingFilter");
        return registration;
    }

    /**
     * 创建一个bean：encodingFilter
     * @return
     */
    @Bean(name = "encodingFilter")
    public Filter encodingFilter() {
        return new CharacterEncodingFilter("UTF-8",true);
    }


    /**
     * 添加静态资源配置
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**/*.ico").addResourceLocations("/");
        registry.addResourceHandler("/app/**").addResourceLocations("/WEB-INF/app/");
        registry.addResourceHandler("/**/*.txt").addResourceLocations("/");
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Bean
    CrossInterceptor crossInterceptor() {
        return new CrossInterceptor();
    }

    @Bean
    LoginInterceptor loginInterceptor() {
        return new LoginInterceptor();
    }


    /**
     * 添加拦截器配置
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(crossInterceptor());
        registry.addInterceptor(loginInterceptor());
        super.addInterceptors(registry);
    }


    /**
     * 视图配置
     */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        super.configureViewResolvers(registry);
        //jsp前缀后缀
        registry.jsp("/WEB-INF/",".jsp");
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
        stringConverter.setWriteAcceptCharset(false);
        converters.add(new ByteArrayHttpMessageConverter());
        converters.add(stringConverter);
        converters.add(new ResourceHttpMessageConverter());
        converters.add(new SourceHttpMessageConverter());
        converters.add(new AllEncompassingFormHttpMessageConverter());
//        if (romePresent) {
//            messageConverters.add(new AtomFeedHttpMessageConverter());
//            messageConverters.add(new RssChannelHttpMessageConverter());
//        }

//        if (jackson2XmlPresent) {
//            messageConverters.add(new MappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperBuilder.xml().applicationContext(this.applicationContext).build()));
//        } else if (jaxb2Present) {
//            messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
//        }


        converters.add(new MappingJackson2HttpMessageConverter(Jackson2ObjectMapperBuilder.json().applicationContext(this.applicationContext).build()));

    }

    //    /**
//     * Must register a static PropertySourcesPlaceholderConfigurer bean in either XML or annotation,
//     * so that Spring @Value know how to interpret ${}
//     *
//     * @return
//     */
//    @Bean(name = "propertySourcesPlaceholderConfigurer")
//    public static PropertySourcesPlaceholderConfigurer propertyConfigIn() {
//        return new PropertySourcesPlaceholderConfigurer();
//    }

}
